package com.nft.service.school.service.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.nft.constant.response.ResponseConstants;
import com.nft.po.NftResponse;
import com.nft.service.school.entity.SysUserEntity;
import com.nft.service.school.mapper.SysUserMapper;
import com.nft.service.school.resp.VerifyCodeResp;
import com.nft.service.school.service.VerifyCodeService;
import com.nft.utils.SendCode;
import com.nft.utils.common.MD5;
import com.nft.utils.dateFormat.SimpleDateFormatUtil;
import com.nft.utils.radom.RadomUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements VerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 短信发送
     *
     * @param phoneNumber 发送的手机号
     * @return ture发送短信成功，false失败
     */
    @Override
    public NftResponse<Boolean> sendVerifyCode(String phoneNumber, int type) {
        Object verifyCodeResp = redisTemplate.opsForValue().get("verifyCode:" + phoneNumber);
        VerifyCodeResp vc = null;
        if (null != verifyCodeResp) {
            vc = JSONUtil.toBean(verifyCodeResp.toString(), VerifyCodeResp.class);
        }
        if (vc == null) {//|| (new Date().getTime() - vc.getLastSendTime().getTime() > 60 * 1000)
            String verifyCode = RadomUtil.getRandomPwd(6);
            if (type == 1) {
                List<SysUserEntity> users = sysUserMapper.selectList(new QueryWrapper<SysUserEntity>().eq("phonenumber", phoneNumber));
                //用户存在就使用登录模板
                if (users!=null&&users.size()>0) {
                    type = 2;
                }
            }
            String content = SendCode.getInstance().sendSmsUtil(phoneNumber, verifyCode, type);
            try {
                //判断短信是否发送成功
                //创建短信验证码对象
                VerifyCodeResp verifyCodeVO = new VerifyCodeResp();
                verifyCodeVO.setLastSendTime(SimpleDateFormatUtil.getNowDate());
                verifyCodeVO.setPhoneNumber(phoneNumber);
                verifyCodeVO.setVerifyCode(MD5.MD5Str(verifyCode));

                //将短信验证码存入Session
                redisTemplate.opsForValue().set("verifyCode:" + phoneNumber, JSON.toJSONString(verifyCodeVO), 1 * 60 * 1000, TimeUnit.MILLISECONDS);
                redisTemplate.opsForValue().set("failCount:" + phoneNumber, 0, 10 * 60 * 1000, TimeUnit.MILLISECONDS);
                return new NftResponse<>(ResponseConstants.SUCCESS_CODE, "发送成功", true);
            } catch (Exception e) {
                e.printStackTrace();
                return new NftResponse<>("500", "发送过于频繁", false);
            }
        } else {
                return new NftResponse<>("500", "发送过于频繁", false);
        }
    }

    @Override
    public Boolean verifyCode(String phoneNumber, String verifyCode) {
        Object failCountObject = redisTemplate.opsForValue().get("failCount:" + phoneNumber);
        if (failCountObject != null) {
            Integer failCount = Integer.valueOf(failCountObject.toString());
            if (failCount >= 5) {
                return false;
            }
        }
        Object verifyCodeResp = redisTemplate.opsForValue().get("verifyCode:" + phoneNumber);
        if (verifyCodeResp == null) {
            return false;
        }
        VerifyCodeResp vc = JSONUtil.toBean(verifyCodeResp.toString(), VerifyCodeResp.class);
        if (vc == null) {
            return false;
        }
        if (!vc.getPhoneNumber().equals(phoneNumber)) {
            return false;
        }
        if (!MD5.MD5Str(verifyCode).equalsIgnoreCase(vc.getVerifyCode())) {
            return false;
        }
        if ((SimpleDateFormatUtil.getNowDate().getTime() - vc.getLastSendTime().getTime() > 2 * 60 * 1000)) {
            return false;
        }
        //redisTemplate.delete("verifyCode:" + phoneNumber);
        redisTemplate.delete("failCount:" + phoneNumber);
        return true;
    }

    /**
     * 将Json字符转换为map对象
     *
     * @param json
     * @return
     */
    public static Map<String, Object> getMapToJson(String json) {
        JSONObject jsonObject = JSONObject.parseObject(json);
        Map<String, Object> valueMap = new HashMap<String, Object>();
        valueMap.putAll(jsonObject);
        return valueMap;
    }
}
